/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.bs.beans;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

/**
 *
 * @author Bone
 */
@Entity
@Table(name = "LANCAMENTO")
public class Lancamento implements Serializable {

    @Transient
    private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
    @Transient
    private BigDecimal total;
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "ID")
    @GeneratedValue(generator = "GEN_LANCAMENTO", strategy = GenerationType.SEQUENCE)
    @SequenceGenerator(name = "GEN_LANCAMENTO", allocationSize = 1, sequenceName = "SQ_LANCAMENTO")
    private Integer id;
    @Basic(optional = false)
    @Column(name = "DATA_LANCAMENTO")
    @Temporal(TemporalType.DATE)
    private Date dataLancamento;
    @Basic(optional = false)
    @Column(name = "DATA_VENCIMENTO")
    @Temporal(TemporalType.DATE)
    private Date dataVencimento;
    @Column(name = "DATA_PAGAMENTO")
    @Temporal(TemporalType.DATE)
    private Date dataPagamento;
    @Basic(optional = false)
    @Column(name = "ENTRADA")
    private short entrada;
    @Basic(optional = false)
    @JoinColumn(name = "TIPO", referencedColumnName = "ID")
    @ManyToOne
    private TipoLancamento tipo;
    @Basic(optional = false)
    @JoinColumn(name = "CONTA")
    @ManyToOne
    private Conta conta;
    @Column(name = "DOCUMENTO")
    private String documento;
    @Basic(optional = false)
    @JoinColumn(name = "PESSOA")
    @ManyToOne
    private Pessoa pessoa;
    // @Max(value=?)  @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
    @Basic(optional = false)
    @Column(name = "VALOR")
    private BigDecimal valor;
    @Column(name = "JUROS")
    private BigDecimal juros;
    @Column(name = "DESCONTO")
    private BigDecimal desconto;
    @Column(name = "OBSERVACAO")
    private String observacao;
    @Column(name = "CONCLUIDO")
    private Short concluido;
    
    public Lancamento() {
        
    }

    public Lancamento(Integer id) {
        this();
        this.id = id;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        Integer oldId = this.id;
        this.id = id;
        changeSupport.firePropertyChange("id", oldId, id);
    }

    public Date getDataLancamento() {
        return dataLancamento;
    }

    public void setDataLancamento(Date dataLancamento) {
        Date oldDataLancamento = this.dataLancamento;
        this.dataLancamento = dataLancamento;
        changeSupport.firePropertyChange("dataLancamento", oldDataLancamento, dataLancamento);
    }

    public Date getDataVencimento() {
        return dataVencimento;
    }

    public void setDataVencimento(Date dataVencimento) {
        Date oldDataVencimento = this.dataVencimento;
        this.dataVencimento = dataVencimento;
        changeSupport.firePropertyChange("dataVencimento", oldDataVencimento, dataVencimento);
    }

    public Date getDataPagamento() {
        return dataPagamento;
    }

    public void setDataPagamento(Date dataPagamento) {
        Date oldDataPagamento = this.dataPagamento;
        this.dataPagamento = dataPagamento;
        changeSupport.firePropertyChange("dataPagamento", oldDataPagamento, dataPagamento);
    }

    public short getEntrada() {
        return entrada;
    }

    public void setEntrada(short entrada) {
        short oldEntrada = this.entrada;
        this.entrada = entrada;
        changeSupport.firePropertyChange("entrada", oldEntrada, entrada);
    }

    public TipoLancamento getTipo() {
        return tipo;
    }

    public void setTipo(TipoLancamento tipo) {
        TipoLancamento oldTipo = this.tipo;
        this.tipo = tipo;
        changeSupport.firePropertyChange("tipo", oldTipo, tipo);
    }

    public Conta getConta() {
        return conta;
    }

    public void setConta(Conta conta) {
        Conta oldConta = this.conta;
        this.conta = conta;
        changeSupport.firePropertyChange("conta", oldConta, conta);
    }

    public String getDocumento() {
        return documento;
    }

    public void setDocumento(String documento) {
        String oldDocumento = this.documento;
        this.documento = documento;
        changeSupport.firePropertyChange("documento", oldDocumento, documento);
    }

    public Pessoa getPessoa() {
        return pessoa;
    }

    public void setPessoa(Pessoa pessoa) {
        Pessoa oldPessoa = this.pessoa;
        this.pessoa = pessoa;
        changeSupport.firePropertyChange("pessoa", oldPessoa, pessoa);
    }

    public BigDecimal getValor() {
        calcular();
        return valor;
    }

    public void setValor(BigDecimal valor) {
        BigDecimal oldValor = this.valor;
        this.valor = valor;
        changeSupport.firePropertyChange("valor", oldValor, valor);
    }

    public BigDecimal getJuros() {
        calcular();
        return juros;
    }

    public void setJuros(BigDecimal juros) {
        BigDecimal oldJuros = this.juros;
        this.juros = juros;
        changeSupport.firePropertyChange("juros", oldJuros, juros);
    }

    public BigDecimal getDesconto() {
        calcular();
        return desconto;
    }

    public void setDesconto(BigDecimal desconto) {
        BigDecimal oldDesconto = this.desconto;
        this.desconto = desconto;
        changeSupport.firePropertyChange("desconto", oldDesconto, desconto);
    }

    public String getObservacao() {
        return observacao;
    }

    public void setObservacao(String observacao) {
        String oldObservacao = this.observacao;
        this.observacao = observacao;
        changeSupport.firePropertyChange("observacao", oldObservacao, observacao);
    }

    public Short getConcluido() {
        return concluido;
    }

    public void setConcluido(Short concluido) {
        Short old = this.concluido;
        this.concluido = concluido;
        changeSupport.firePropertyChange("concluido", old, concluido);
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Lancamento)) {
            return false;
        }
        Lancamento other = (Lancamento) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.bs.vews.Lancamento[ id=" + id + " ]";
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        changeSupport.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        changeSupport.removePropertyChangeListener(listener);
    }

    private void calcular() {
        if (valor == null) {
            valor = new BigDecimal(0);
        }
        if (juros == null) {
            juros = new BigDecimal(0);
        }
        if (desconto == null) {
            desconto = new BigDecimal(0);
        }
        setTotal(valor.add(juros).subtract(desconto));

        if (entrada == 0) {
            if (valor.doubleValue() > 0) {
                setValor(valor.multiply(new BigDecimal(-1)));
                return;
            }
            if (desconto.doubleValue() > 0) {
                setDesconto(desconto.multiply(new BigDecimal(-1)));
                return;
            }
            if (juros.doubleValue() > 0) {
                setJuros(juros.multiply(new BigDecimal(-1)));
                return;
            }
            if (total.doubleValue() > 0) {
                setTotal(total.multiply(new BigDecimal(-1)));
                return;
            }
        }
    }

    public BigDecimal getTotal() {
        return total;
    }

    public void setTotal(BigDecimal total) {
        BigDecimal old = this.total;
        this.total = total;
        changeSupport.firePropertyChange("total", old, total);
    }
}
